//
// Created by Asus on 2025/6/1.
//

#include <iostream>
#include <bits/ostream.tcc>
using namespace std;

void demo01() {
    int a = 10;
    int &b = a;
    cout << "a: " << a << endl;
    cout << "b: " << b << endl;
    b = 100;
    cout << "a: " << a << endl;
    cout << "b: " << b << endl;
    int &ref = a;
    // int &ref2; 引用必须初始化
    ref = b; // 这里不是重新绑定引用，而是将b的值赋给a，因为ref始终是a的别名
}

int &getValue() {
    static int num = 100; // 使用静态变量，确保其生命周期贯穿整个程序运行过程
    return num;
}

void demo02() {
    int &result = getValue();
    cout << "result: " << result << endl;
    result = 200; // 通过引用返回值修改了静态变量的值
    cout << "result after modification: " << result << endl;
}

//1. 值传递
void mySwap01(int a, int b) {
    int temp = a;
    a = b;
    b = temp;
}

//2. 地址传递
void mySwap02(int* a, int* b) {
    int temp = *a;
    *a = *b;
    *b = temp;
}

//3. 引用传递
void mySwap03(int& a, int& b) {
    int temp = a;
    a = b;
    b = temp;
}

void demo03() {
    int a = 10;
    int b = 20;

    mySwap01(a, b);
    cout << "a:" << a << " b:" << b << endl;

    mySwap02(&a, &b);
    cout << "a:" << a << " b:" << b << endl;

    mySwap03(a, b);
    cout << "a:" << a << " b:" << b << endl;
}

// 返回局部变量
int &test01() {
    int a = 10;
    cout << "a: " << (unsigned long long) &a << endl;
    return a;
}

// 返回静态变量引用
int &test02() {
    static int a = 10;
    cout << "a: " << (unsigned long long) &a << endl;
    return a;
}

void demo04() {
    //不能返回局部变量的引用
    int &ref = test01();
    // cout << "ref: " << ref << endl; // 报错SIGSEGV
    //如果函数做左值(有持久的内存地址，可被修改)，那么必须返回引用
    test02() = 30;
    int& ref2 = test02();
    cout << "ref2 = " << ref2 << endl;
}

//发现是引用，转换为 int* const ref = &a; 指针指向不能变，值可以变
void func(int &ref) {
    ref = 100;
}

void demo05() {
    int a = 10;
    //自动转换为 int* const ref = &a; 指针常量是指针指向不可改，也说明为什么引用不可更改
    int &ref = a;
    ref = 20; //内部发现ref是引用，自动帮我们转换为: *ref = 20;
    cout << "a:" << a << endl;
    cout << "ref:" << ref << endl;
    func(a);
    cout << "a:" << a << endl;
    cout << "ref:" << ref << endl;
}

//引用使用的场景，通常用来修饰形参
void showValue(const int &value) {
    cout << "value: " << value << endl;
}

void demo06() {
    // int &ref = 10;引用本身需要一个合法的内存空间，因此这行错误
    //加入const就可以了，编译器优化代码，int temp = 10; const int& ref = temp;
    const int &ref = 10;
    // ref = 100;//加入const后不可以修改变量
    cout << "ref = " << ref << endl;
    // 函数中利用常量引用防止误操作修改实参
    int a = 10;
    showValue(a);
    cout << "a = " << a << endl;
    // 等价const int &re
    int const &ref2 = 10;
    showValue(ref2);
}

int main(int argc, char *argv[]) {
    // demo01();
    // demo02();
    // demo03();
    // demo04();
    // demo05();
    demo06();
    return 0;
}
